package org.ielts.action.base;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import java.util.Date;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.ss.usermodel.Cell;

import org.ielts.action.BaseAction;
import org.ielts.domain.LearnStatus;
import org.ielts.domain.Sex;
import org.ielts.domain.base.Course;
import org.ielts.domain.base.SignCourse;
import org.ielts.domain.base.Student;
import org.ielts.domain.log.SchoolLog;
import org.ielts.domain.log.SignCourseLog;
import org.ielts.domain.report.StudentQuery;
import org.ielts.domain.security.User;
import org.ielts.service.ConsultantService;
import org.ielts.service.CourseService;
import org.ielts.service.SignCourseService;
import org.ielts.service.StudentService;
import org.ielts.service.TutorService;
import org.ielts.service.security.UserService;
import org.ielts.util.MapListWapper;
import org.ielts.util.SimpleCellReader;
import org.ielts.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.validation.BindException;

import com.yifeng.TimePair;
import com.yifeng.dto.DtoTable;
import com.yifeng.dto.FormRow;
import com.yifeng.dto.IDtoRow;
import com.yifeng.dto.UploadFile;
import com.yifeng.dto.ValueReader;
import com.yifeng.dto.ValueReaderBuilder;
import com.yifeng.modules.annotations.Operation;
import com.yifeng.poi.CellReader;
import com.yifeng.poi.ExcelUtils;
import com.yifeng.sequence.ISeqService;
import com.yifeng.struts2.RequestParameters;
import com.yifeng.struts2.ResultParameters;
import com.yifeng.utils.CalendarUtils;
import com.yifeng.utils.JsonResultBuilder;
import com.yifeng.utils.PageUtils;
import com.yifeng.web.Pagers;
import com.yifeng.web.Paginations;

import static com.yifeng.struts2.RequestParameters.*;
import static com.yifeng.struts2.ResultParameters.*;
import static com.yifeng.struts2.ResultConstants.*;
import static com.yifeng.struts2.ActionUtils.*;

public class StudentAction extends BaseAction {

	@Autowired
	StudentService studentService;

	@Autowired
	private UserService userService;

	@Autowired
	private SignCourseService signCourseService;

	@Operation(result = JSON)
	public String regFigner() throws Exception {
		String sid = form.readString("sid");
		String figner = form.readString("figner");
		boolean re = studentService.registerFigner(sid, figner);
		setJson(JsonResultBuilder.success(true).add("result", re).json());
		return JSON;
	}

	@Operation(result = JSON)
	public String identifiy() throws Exception {
		String figner = form.readString("figner");
		String re = studentService.identificationFigner(figner);
		setJson(JsonResultBuilder.success(true).add("result", re).json());
		return JSON;
	}

	@Operation(result = FILL)
	public String createStudent() {

		String no = nextNo();

		put("no", no);

		return FILL;
	}

	@Operation(result = JSON)
	public String doCreateStudent() {
		String no = form.readString("no");
		String name = form.readString("name");

		int age = valueReader.name("age").defaultValue(0).intValue();
		Date birthday = null;
		if (age != 0) {
			birthday = DateUtils.addYears(new Date(), -age);
		}

		String job = form.readString("job");
		String address = form.readString("address");
		String phone = form.readString("phone");
		String zip = form.readString("zip");
		String mobile = form.readString("mobile");
		String education = form.readString("education");
		String stuId = form.readString("stuId");
		String email = form.readString("email");
		String title = form.readString("title");

		Sex sex = Sex.NotSet;
		String s = form.readString("sex");
		if (org.apache.commons.lang.StringUtils.isNotBlank(s)) {
			sex = Sex.valueOf(s);
		}

		Student student = new Student();
		student.setAddress(address);
		student.setBirthday(birthday);
		student.setConsultStarred(false);
		student.setEducation(education);
		student.setJob(job);
		student.setMobile(mobile);
		student.setName(name);
		student.setNo(no);
		student.setPhone(phone);
		student.setSex(sex);
		student.setZip(zip);
		student.setStuId(stuId);
		student.setEmail(email);
		student.setTitle(title);

		studentService.createStudent(student);

		setJson(JsonResultBuilder.success(true).msg("创建学员成功").add("id", student.getId()).json());

		return JSON;
	}

	@Autowired
	ISeqService seqService;

	public String nextNo() {
		String day = new SimpleDateFormat("yyyyMMdd").format(new Date());
		long no = seqService.next("student.no" + day);

		String strNo = String.format("%04d", no);

		return local + day + strNo;
	}

	// 20表示校区
	String local = "20";

	@Operation(result = JSON)
	public String doCheckStudentName() {
		String name = form.readString("name");

		Iterable<Student> students = studentService.findByName(name);
		boolean exists = false;
		for (Student student : students) {
			exists = true;
		}

		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "roles", "creator", "student", "courseType", "orderLessonLogs",
				"signCourseLogs" });

		JSONArray jsonArray = JSONArray.fromObject(students, jsonConfig);

		setJson(JsonResultBuilder.success(exists).add("students", jsonArray).json());

		return JSON;
	}

	@Operation(result = JSON)
	public String doCheckMobile() {
		String mobile = form.readString("mobile");

		Iterable<Student> students = studentService.findByMobile(mobile);

		boolean exists = false;
		for (Student student : students) {
			exists = true;
		}

		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "roles", "creator", "student", "courseType", "orderLessonLogs",
				"signCourseLogs" });

		JSONArray jsonArray = JSONArray.fromObject(students, jsonConfig);

		setJson(JsonResultBuilder.success(exists).add("students", jsonArray).json());

		return JSON;
	}

	@Operation(result = JSON)
	public String searchStudent() {
		String text = form.readString("searchText");

		if (StringUtils.isBlank(text)) {
			setJson(JsonResultBuilder.success(true).add("students", new JSONArray()).json());

			return JSON;
		}

		text = text.trim();
		char c = text.charAt(0);

		Iterable<Student> students;

		if (c >= '0' && c <= '9') {
			students = studentService.findByStuId(text);
		} else if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
			text = text.toLowerCase();
			students = studentService.findByPinyin(text);
		} else {
			students = studentService.findByName(text);
		}

		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "roles", "creator", "student", "courseType", "orderLessonLogs",
				"signCourseLogs", "teachings", "schoolLogs" });

		JSONArray jsonArray = JSONArray.fromObject(students, jsonConfig);

		setJson(JsonResultBuilder.success(true).add("students", jsonArray).json());

		return JSON;
	}

	@Autowired
	ConsultantService consultantService;

	@Autowired
	TutorService tutorService;

	@Autowired
	CourseService courseService;

	@Operation(result = FILL)
	public String listStudent() {
		StudentQuery studentQuery = buildStudentQuery(form);

		Pageable pageable = getPageable();

		Page<Student> students = studentService.findAll(studentQuery, pageable);
		put("students", students);

		put(PAGINATIONS, new Paginations(students));

		Iterable<User> consultants = consultantService.listConsultant();
		put("consultants", consultants);

		Iterable<User> tutors = tutorService.listTutor();
		put("tutors", tutors);

		Iterable<Course> courses = courseService.findAll();
		put("courses", courses);

		StringBuilder sb = buildSearchString(studentQuery, consultants, tutors, courses);

		put("search", sb);

		return FILL;
	}

	private StudentQuery buildStudentQuery(FormRow form) {
		String name = form.readString("name");
		String[] learnStatus = form.readStrings("learnStatus");
		String[] consultStarred = form.readStrings("consultStarred");
		String[] consultant = form.readStrings("consultant");
		String[] tutor = form.readStrings("tutor");
		String[] course = form.readStrings("course");
		String onlyVoid = form.readString("onlyVoid");

		// 报名时间
		Date signStartDate = valueReader.name("signStartDate").defaultValue(null).dateValue("yyyy-MM-dd");
		Date signEndDate = valueReader.name("signEndDate").defaultValue(null).dateValue("yyyy-MM-dd");

		// 开始上课时间
		Date startDate = valueReader.name("startDate").defaultValue(null).dateValue("yyyy-MM-dd");
		Date endDate = valueReader.name("endDate").defaultValue(null).dateValue("yyyy-MM-dd");

		StudentQuery studentQuery = new StudentQuery();

		if (StringUtils.isNotBlank(onlyVoid)) {
			studentQuery.setOnlyVoid(true);
		}

		// 用户名
		if (StringUtils.isNotBlank(name)) {
			studentQuery.setName(name.trim());
		}
		// 学习状态
		if (learnStatus.length > 0) {
			LearnStatus[] learnStatuss = new LearnStatus[learnStatus.length];

			for (int i = 0; i < learnStatuss.length; i++) {
				LearnStatus status = LearnStatus.valueOf(learnStatus[i]);
				learnStatuss[i] = status;
			}

			studentQuery.addLearnStatus(learnStatuss);
		}
		// 咨询师关注
		if (consultStarred.length > 0) {
			boolean[] consultStarreds = new boolean[consultStarred.length];

			for (int i = 0; i < consultStarreds.length; i++) {
				boolean starred = consultStarred[i].equals("true") ? true : false;
				consultStarreds[i] = starred;
			}

			studentQuery.addConsultStarred(consultStarreds);
		}

		// 咨询师筛选
		if (consultant.length > 0) {
			studentQuery.addConsultant(consultant);
		}

		// 辅导员筛选
		if (tutor.length > 0) {
			studentQuery.addTutor(tutor);
		}

		// 课程筛选
		if (course.length > 0) {
			studentQuery.addCourse(course);
		}

		// 报名时间
		if (signStartDate != null && signEndDate != null) {
			signEndDate = DateUtils.addDays(signEndDate, 1);

			TimePair timePair = new TimePair();
			timePair.setStartDate(signStartDate);
			timePair.setEndDate(signEndDate);

			studentQuery.setSignDate(timePair);
		}

		// 开始上课时间
		if (startDate != null && endDate != null) {
			endDate = DateUtils.addDays(endDate, 1);

			TimePair timePair = new TimePair();
			timePair.setStartDate(startDate);
			timePair.setEndDate(endDate);

			studentQuery.setCourseDate(timePair);
		}
		return studentQuery;
	}

	private StringBuilder buildSearchString(StudentQuery studentQuery, Iterable<User> consultants,
			Iterable<User> tutors, Iterable<Course> courses) {
		StringBuilder sb = new StringBuilder();

		if (studentQuery.hasConsultStarred()) {
			if (studentQuery.getConsultStarred().length != 2) {
				if (studentQuery.getConsultStarred()[0]) {
					sb.append("在咨询中，");
				} else {
					sb.append("不在咨询中，");
				}
			}
		}

		if (studentQuery.hasConsultant()) {
			sb.append("由");

			for (String consultantId : studentQuery.getConsultant()) {
				User user = findUser(consultants, consultantId);

				sb.append("<strong>");
				sb.append(user.getName());
				sb.append("</strong>");

				sb.append("，");
			}

			sb.setLength(sb.length() - 1);

			sb.append("咨询，");
		}

		if (studentQuery.hasCourse()) {
			sb.append("注册了");

			for (String courseId : studentQuery.getCourse()) {
				Course c = findCourse(courses, courseId);

				sb.append("<strong>");
				sb.append(c.getName());
				sb.append("</strong>");

				sb.append(",");
			}

			sb.setLength(sb.length() - 1);
			sb.append("课程，");
		}

		if (studentQuery.hasCourseDate()) {
			sb.append("开课时间：");
			sb.append("<strong>");
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
			sb.append(simpleDateFormat.format(studentQuery.getCourseDate().getStartDate()));
			sb.append("-");

			Date date = DateUtils.addDays(studentQuery.getCourseDate().getEndDate(), -1);

			sb.append(simpleDateFormat.format(date));
			sb.append("</strong>");
			sb.append("，");
		}

		/*
		 * if (studentQuery.hasLearnStatus()) { sb.append("在读状态：");
		 * 
		 * for (LearnStatus leanStatus : studentQuery.getLearnStatus()) { switch
		 * (leanStatus) { case Finished: sb.append("已结课,"); break; case
		 * Learning: sb.append("在读中,"); break; case Freeze: sb.append("已冻结,");
		 * break; default: break; } } }
		 */
		if (studentQuery.hasSignDate()) {
			sb.append("报名时间：");

			sb.append("<strong>");

			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
			sb.append(simpleDateFormat.format(studentQuery.getSignDate().getStartDate()));
			sb.append("-");

			Date date = DateUtils.addDays(studentQuery.getSignDate().getEndDate(), -1);

			sb.append(simpleDateFormat.format(date));

			sb.append("</strong>");
			sb.append("，");
		}

		if (studentQuery.hasTutor()) {
			sb.append("由");

			for (String tutorId : studentQuery.getTutor()) {
				User user = findUser(tutors, tutorId);

				sb.append("<strong>");
				sb.append(user.getName());
				sb.append("</strong>");

				sb.append(",");
			}

			sb.setLength(sb.length() - 1);

			sb.append("辅导，");
		}
		if (sb.length() > 1) {
			sb.setLength(sb.length() - 1);
		}
		return sb;
	}

	private Course findCourse(Iterable<Course> courses, String courseId) {
		for (Course course : courses) {
			if (course.getId().equals(courseId)) {
				return course;
			}
		}

		return new Course();
	}

	private User findUser(Iterable<User> consultants, String consultantId) {
		for (User user : consultants) {
			if (user.getId().equals(consultantId)) {
				return user;
			}
		}

		return new User();
	}

	@Operation(result = FILL)
	public String modifyStudent() {
		String id = form.readString("id");

		Student student = studentService.findOne(id);

		put("student", student);

		return FILL;
	}

	@Operation(result = FILL)
	public String doModifyStudent() {
		String id = form.readString("id");
		String name = form.readString("name");

		int age = valueReader.name("age").defaultValue(0).intValue();
		Date birthday = null;
		if (age != 0) {
			birthday = DateUtils.addYears(new Date(), -age);
		}

		String job = form.readString("job");
		String address = form.readString("address");
		String phone = form.readString("phone");
		String zip = form.readString("zip");
		String mobile = form.readString("mobile");
		String education = form.readString("education");
		String stuId = form.readString("stuId");
		String title = form.readString("title");
		String email = form.readString("email");

		Sex sex = Sex.NotSet;
		String s = form.readString("sex");
		if (org.apache.commons.lang.StringUtils.isNotBlank(s)) {
			sex = Sex.valueOf(s);
		}

		studentService.modifyStudent(id, name, sex, title, email, birthday, job, address, phone, zip, mobile,
				education, stuId);

		setJson(JsonResultBuilder.success(true).msg("修改学员信息成功").add("id", id).json());
		return JSON;
	}

	class NumReader implements CellReader {

		public Object read(HSSFCell cell) {
			String str = cell.getStringCellValue();
			return str;
		}

	}

	class StringReader implements CellReader {
		private boolean numberFirst = true;

		public StringReader() {

		}

		public StringReader(boolean numberFirst) {
			this.numberFirst = numberFirst;
		}

		public Object read(HSSFCell cell) {
			Object value = null;
			if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
				value = cell.getStringCellValue();
			} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
				if (numberFirst) {
					try {
						double d = cell.getNumericCellValue();

						DecimalFormat decimalFormat = new DecimalFormat("0");
						value = decimalFormat.format(d);

					} catch (Exception ex) {
						value = cell.getDateCellValue();
					}
				} else {
					try {
						value = cell.getDateCellValue();
					} catch (Exception ex) {
						value = cell.getNumericCellValue();
					}
				}

			}

			return value;
		}
	}

	private String[] name;
	private String[] stuid;
	private String[] cardId;
	private Date[] signTime;
	private String[] lessonCard;
	private String[] term;
	private String[] coureId;
	private String[] ccid;
	private String[] tutorId;
	private Date[] beginTime;
	private Date[] endTime;
	private int[] times;

	public void setLessonCard(String[] lessonCard) {
		this.lessonCard = lessonCard;
	}

	public void setStuid(String[] stuid) {
		this.stuid = stuid;
	}

	public void setSignTime(Date[] signTime) {
		this.signTime = signTime;
	}

	public void setName(String[] name) {
		this.name = name;
	}

	public void setCardId(String[] cardid) {
		this.cardId = cardid;
	}

	public void setTerm(String[] term) {
		this.term = term;
	}

	public void setCoureId(String[] coureId) {
		this.coureId = coureId;
	}

	public void setCcid(String[] ccid) {
		this.ccid = ccid;
	}

	public void setTutorId(String[] tutorId) {
		this.tutorId = tutorId;
	}

	public void setBeginTime(Date[] beginTime) {
		this.beginTime = beginTime;
	}

	public void setEndTime(Date[] endTime) {
		this.endTime = endTime;
	}

	public void setTimes(int[] times) {
		this.times = times;
	}
}
